# include "XMLItem.h"
# include <algorithm>
# include <iostream>

ZDSJ::XmlItem::XmlItem()
{
    
}

ZDSJ::XmlItem::XmlItem(const std::string& _name) : m_item_name(new std::string(_name))
{
    this->m_item = new std::vector<XmlItem*>();
    this->m_properties = new std::map<std::string, std::string>;
}

ZDSJ::XmlItem::XmlItem(const std::string& _name, const std::string& _value)
    : XmlItem(_name)
{
    this->m_item_value = new std::string(_value);
}

void ZDSJ::XmlItem::name(const char* _name, size_t _len){
    delete this->m_item_name;
    this->m_item_name = new std::string(_name, _len);
}

void ZDSJ::XmlItem::value(const char* _value, size_t _len){
    delete this->m_item_value;
    this->m_item_value = new std::string(_value, _len);
}

const std::string& ZDSJ::XmlItem::name() const{
    return *this->m_item_name;
}

const std::string& ZDSJ::XmlItem::value() const{
    return *this->m_item_value;
}

ZDSJ::XmlItem* ZDSJ::XmlItem::item(size_t _index){
    if(_index > this->m_item->size() - 1){
        return nullptr;
    }
    return this->m_item->at(_index);
}

const std::vector<ZDSJ::XmlItem*>* ZDSJ::XmlItem::items() const{
    if (this->m_item == nullptr || this->m_item->empty()) {
        return nullptr;
    }
    return this->m_item;
}

std::string&& ZDSJ::XmlItem::property(const std::string& _key) const{
    auto item = this->m_properties->find(_key);
    if(item == this->m_properties->end()){
        return "";
    }
    return std::move(this->m_properties->find(_key)->second);
}

void ZDSJ::XmlItem::property(const char* _key, size_t _key_len, const char* _value, size_t _value_len){
    std::string key(_key, _key_len);
    std::string value(_value, _value_len);
    if (this->m_properties == nullptr) {
        this->m_properties = new std::map<std::string, std::string>;
    }
    auto item = this->m_properties->find(key);
    if(item == this->m_properties->end()){
        this->m_properties->emplace(std::make_pair(key, value));
        return;
    }
    item->second = _value;
}

void ZDSJ::XmlItem::addItem(ZDSJ::XmlItem* _value){
    if (this->m_item == nullptr) {
        this->m_item = new std::vector<XmlItem*>();
    }
    this->m_item->push_back(_value);
}

size_t ZDSJ::XmlItem::keys(std::vector<std::string>* _keys) const{
    if(_keys == nullptr){
        return 0;
    }
    if(!_keys->empty()){
        return 0;
    }
    if(this->m_properties == nullptr){
        return 0;
    }
    std::for_each(this->m_properties->begin(), this->m_properties->end(), [&](std::pair<std::string, std::string> _item){
        _keys->push_back(_item.first);
    });
    return _keys->size();
}


ZDSJ::XmlItem::~XmlItem()
{
    if(this->m_item != nullptr){
        std::for_each(this->m_item->begin(), this->m_item->end(), [](XmlItem* _item){
            delete _item;
        });
        delete this->m_item;
    }
    if(this->m_properties != nullptr){
        delete this->m_properties;
    }
    delete this->m_item_name;
    delete this->m_item_value;
}